package org.dromara.workflow.flowable.cmd;

import org.dromara.common.core.exception.ServiceException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
import org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：修改流程状态
 */
/**
 * 更新业务状态命令类
 * 本类实现了Command接口，用于执行更新业务状态的操作
 * 该操作返回一个Boolean类型的值，表示更新操作是否成功
 */
public class UpdateBusinessStatusCmd implements Command<Boolean> {

    /**
     * 处理实例ID，唯一标识一个流程实例。
     * 这是一个关键属性，用于跟踪和管理流程的整个生命周期。
     */
    private final String processInstanceId;

    /**
     * 状态字段，用于记录当前流程实例的状态。
     * 状态可能包括但不限于"进行中"、"已完成"、"已取消"等，它提供了流程实例当前所处阶段的信息。
     */
    private final String status;

    /**
     * 更新业务状态命令类构造函数
     *
     * @param processInstanceId 流程实例ID，用于标识业务流程的唯一实例
     * @param status 业务状态，表示业务当前所处的状态
     */
    public UpdateBusinessStatusCmd(String processInstanceId, String status) {
        this.processInstanceId = processInstanceId;
        this.status = status;
    }

    /**
     * 更新历史流程实例的业务状态
     *
     * @param commandContext 命令上下文，用于获取历史流程实例实体管理器
     * @return Boolean 返回执行结果，如果成功更新业务状态返回true
     */
    @Override
    public Boolean execute(CommandContext commandContext) {
        try {
            // 通过命令上下文工具类获取历史流程实例实体管理器
            HistoricProcessInstanceEntityManager manager = CommandContextUtil.getHistoricProcessInstanceEntityManager();
            // 通过管理器根据ID查找历史流程实例实体
            HistoricProcessInstanceEntity processInstance = manager.findById(processInstanceId);
            // 更新历史流程实例的业务状态
            processInstance.setBusinessStatus(status);
            // 更新数据库中的历史流程实例实体
            manager.update(processInstance);
            // 返回成功执行更新操作的标志
            return true;
        } catch (Exception e) {
            // 如果发生异常，抛出业务服务异常
            throw new ServiceException(e.getMessage());
        }
    }
}
